package com.whmall.service.crm.module.companyuser.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.whmall.component.enumeration.MpNotifyBitmapEnum;
import com.whmall.component.enumeration.ThirdPlatformTypeEnum;
import com.whmall.component.util.BeanUtilsWhmall;
import com.whmall.service.crm.entity.dto.companyuser.*;
import com.whmall.service.crm.enumeration.CompanyUserPlatformIsBindEnum;
import com.whmall.service.crm.enumeration.ThirdPlatformFollowStatusEnum;
import com.whmall.service.crm.module.companyuser.CompanyUserPlatformService;
import com.whmall.service.crm.module.companyuser.dao.CompanyUserInformationMapper;
import com.whmall.service.crm.module.companyuser.dao.CompanyUserPlatformMapper;
import com.whmall.service.crm.module.companyuser.entity.CompanyUserPlatformDO;
import com.whmall.service.crm.module.companyuser.entity.qo.CompanyUserPlatformQO;
import com.whmall.service.crm.util.StringBitmapUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class CompanyUserPlatformServiceImpl implements CompanyUserPlatformService {

    @Autowired
    private CompanyUserPlatformMapper companyUserPlatformMapper;

    @Autowired
    private CompanyUserInformationMapper companyUserInformationMapper;

    @Override
    public List<String> listValidByUserIds(Integer index, List<Long> userIds, Integer thirdPlatformType) {
        if(CollectionUtils.isEmpty(userIds) || index == null || thirdPlatformType == null) {
            return Collections.emptyList();
        }
        return companyUserPlatformMapper.listValid(userIds, thirdPlatformType)
                .stream().filter(e ->
                        //按业务开关过滤
                        e.getNotifyBitmap().length() <= index || e.getNotifyBitmap().charAt(index) == '0')
                .map(CompanyUserPlatformDO::getPlatformId).distinct().collect(Collectors.toList());
    }

    @Override
    public Map<Long, List<String>> mapValidByUserIds(Integer index, List<Long> userIds, Integer thirdPlatformType) {
        if(CollectionUtils.isEmpty(userIds) || index == null || thirdPlatformType == null) {
            return new HashMap<>(0);
        }
        // 全部需要发送的用户平台
        return companyUserPlatformMapper.listValid(userIds, thirdPlatformType)
                .stream()
                // 先过滤
                .filter(e ->
                        //按业务开关过滤
                        e.getNotifyBitmap().length() <= index || e.getNotifyBitmap().charAt(index) == '0')
                .collect(Collectors.groupingBy(CompanyUserPlatformDO::getUserId,
                        Collectors.mapping(CompanyUserPlatformDO::getPlatformId, Collectors.toList())));
    }

    @Override
    public String getSelectByUserId(Long userId, String openId, Integer thirdPlatformType) {
        List<CompanyUserPlatformDO> companyUserPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                        .userId(userId)
                        .thirdPlatformType(thirdPlatformType)
                        .platformId(openId).build());
        if (companyUserPlatformDOS.isEmpty()){
            return null;
        }
        CompanyUserPlatformDO companyUserPlatformDO = companyUserPlatformDOS.get(0);
        if (companyUserPlatformDO == null){
            return null;
        }
        if (companyUserPlatformDO.getIsBind() == 0){
            return null;
        }
        return companyUserPlatformDO.getNotifyBitmap() != null ? companyUserPlatformDO.getNotifyBitmap() : "";
    }

    @Override
    public List<CompanyUserPlatformKeyFieldRspDTO> listBy(CompanyUserPlatformListByReqDTO reqDTO) {
        CompanyUserPlatformQO qo = new CompanyUserPlatformQO();
        BeanUtils.copyProperties(reqDTO, qo);
        return companyUserPlatformMapper.listBy(qo)
                .stream().map(e -> {
                    CompanyUserPlatformKeyFieldRspDTO rspDTO = new CompanyUserPlatformKeyFieldRspDTO();
                    BeanUtils.copyProperties(e, rspDTO);
                    BeanUtilsWhmall.converDefaultTime(rspDTO);
                    return rspDTO;
        }).collect(Collectors.toList());
    }

    @Override
    public Boolean isBinding(Long userId, String openId, Integer thirdPlatformType) {
        List<CompanyUserPlatformDO> companyUserPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                        .userId(userId)
                        .thirdPlatformType(thirdPlatformType)
                        .platformId(openId).build());
        if (companyUserPlatformDOS.isEmpty()){
            return null;
        }
        CompanyUserPlatformDO companyUserPlatformDO = companyUserPlatformDOS.get(0);
        if (companyUserPlatformDO == null){
            return false;
        }
        if (companyUserPlatformDO.getIsBind() == 0){
            return false;
        }
        return true;
    }

    @Override
    public Integer select(Long userId, String openId, Integer thirdPlatformType, Map<Integer, Integer> indexes) {
        List<CompanyUserPlatformDO> companyUserPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                        .userId(userId)
                        .thirdPlatformType(thirdPlatformType)
                        .platformId(openId).build());
        if (companyUserPlatformDOS.isEmpty()){
            return null;
        }
        CompanyUserPlatformDO companyUserPlatformDO = companyUserPlatformDOS.get(0);
        if (companyUserPlatformDO == null){
            throw new IllegalArgumentException("成功");
        }
        String notifyBitmap = ObjectUtil.isNotNull(companyUserPlatformDO.getNotifyBitmap()) ? companyUserPlatformDO.getNotifyBitmap() : "";
        for (Map.Entry<Integer, Integer> index : indexes.entrySet()){
            if(MpNotifyBitmapEnum.fromValue(index.getKey()) != null){
                if (index.getValue().equals(0)){
                    notifyBitmap = StringBitmapUtils.asTrue(notifyBitmap, index.getKey());
                }else {
                    notifyBitmap = StringBitmapUtils.asFalse(notifyBitmap, index.getKey());
                }
            }
        }
        CompanyUserPlatformDO temp = new CompanyUserPlatformDO();
        temp.setId(companyUserPlatformDO.getId());
        temp.setNotifyBitmap(notifyBitmap);
        return companyUserPlatformMapper.updateByPrimaryKeySelective(temp);
    }

    @Override
    @Transactional
    public Long follow(CompanyUserPlatformSaveReqDTO reqDTO) {

        List<CompanyUserPlatformDO> companyUserPlatformDOS = companyUserPlatformMapper.listBy(
                CompanyUserPlatformQO.builder()
                .platformId(reqDTO.getPlatformId()).thirdPlatformType(reqDTO.getThirdPlatformType())
                .build());
        if (CollUtil.isNotEmpty(companyUserPlatformDOS)){
            log.info("关注流程已有"+companyUserPlatformDOS.size()+"条记录");
            companyUserPlatformDOS.forEach(companyUserPlatformDO -> {
                companyUserPlatformDO.setThirdPlatformFollowStatus(ThirdPlatformFollowStatusEnum.FOLLOWED.getValue());
                //companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
                companyUserPlatformDO.setThirdPlatformType(reqDTO.getThirdPlatformType());
                companyUserPlatformDO.setUpdateTime(new Date());
                companyUserPlatformMapper.updateByPrimaryKeySelective(companyUserPlatformDO);
            });
            return companyUserPlatformDOS.get(0).getId();
        }
        CompanyUserPlatformDO companyUserPlatformDO = new CompanyUserPlatformDO();
        companyUserPlatformDO.setPlatformId(reqDTO.getPlatformId());
        companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
        companyUserPlatformDO.setThirdPlatformType(reqDTO.getThirdPlatformType());
        companyUserPlatformDO.setThirdPlatformFollowStatus(ThirdPlatformFollowStatusEnum.FOLLOWED.getValue());
        companyUserPlatformDO.setCreateTime(new Date());
        companyUserPlatformDO.setUserId(0L);
        companyUserPlatformDO.setPlatformToken("");
        companyUserPlatformDO.setNickname(reqDTO.getNickName());
        companyUserPlatformDO.setAvatar(reqDTO.getAvatar());
        companyUserPlatformDO.setUniqueId(reqDTO.getUniqueId());
        companyUserPlatformMapper.insertSelective(companyUserPlatformDO);
        log.info("关注流程已插入记录");
        return companyUserPlatformDO.getId();
    }

    @Override
    @Transactional
    public void unfollow(CompanyUserPlatformUnFollowReqDTO reqDTO) {

        List<CompanyUserPlatformDO> companyUserPlatformDOS = companyUserPlatformMapper.listBy(
                CompanyUserPlatformQO.builder().platformId(reqDTO.getPlatformId())
                        .thirdPlatformType(reqDTO.getThirdPlatformType()).build());
        if (CollUtil.isNotEmpty(companyUserPlatformDOS)){
            companyUserPlatformDOS.forEach(companyUserPlatformDO -> {
                companyUserPlatformDO.setThirdPlatformFollowStatus(ThirdPlatformFollowStatusEnum.CANCEL_FOLLOWED.getValue());
                companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
                companyUserPlatformMapper.updateByPrimaryKeySelective(companyUserPlatformDO);
            });
        }
    }

    @Override
    @Transactional
    public AccessTokenSaveRspDTO saveAccessToken(AccessTokenSaveReqDTO reqDTO) {

        List<CompanyUserPlatformDO> userPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                .platformId(reqDTO.getPlatformId()).build());
        if (CollUtil.isEmpty(userPlatformDOS)){
            CompanyUserPlatformDO companyUserPlatformDO = new CompanyUserPlatformDO();
            companyUserPlatformDO.setPlatformId(reqDTO.getPlatformId());
            companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
            companyUserPlatformDO.setThirdPlatformType(reqDTO.getThirdPlatformType());
            companyUserPlatformDO.setThirdPlatformFollowStatus(ThirdPlatformFollowStatusEnum.NOT_FOLLOWED.getValue());
            companyUserPlatformDO.setCreateTime(new Date());
            companyUserPlatformDO.setUserId(0l);
            companyUserPlatformDO.setPlatformToken(reqDTO.getAccessToken());
            companyUserPlatformDO.setNickname(reqDTO.getNickName());
            companyUserPlatformDO.setAvatar(reqDTO.getAvatar());
            companyUserPlatformDO.setUniqueId(reqDTO.getUniqueId());
            companyUserPlatformDO.setRefreshToken(reqDTO.getRefreshToken());
            companyUserPlatformMapper.insertSelective(companyUserPlatformDO);
            return AccessTokenSaveRspDTO.builder().isAutoLogin(false).build();
        }

        long count = userPlatformDOS.stream().filter(e -> e.getIsBind().equals(1)).count();
        userPlatformDOS.stream().forEach(userPlatformDO -> {
                    userPlatformDO.setPlatformToken(reqDTO.getAccessToken());
                    userPlatformDO.setThirdPlatformType(reqDTO.getThirdPlatformType());
                    userPlatformDO.setRefreshToken(reqDTO.getRefreshToken());
                    userPlatformDO.setNickname(reqDTO.getNickName());
                    userPlatformDO.setAvatar(reqDTO.getAvatar());
                    userPlatformDO.setUniqueId(reqDTO.getUniqueId());
                    userPlatformDO.setUpdateTime(new Date());
                    companyUserPlatformMapper.updateByPrimaryKeySelective(userPlatformDO);
                });
        if (count == 1){
            Long userId =  userPlatformDOS.stream().filter(e -> e.getIsBind()
                    .equals(1)).findFirst().get().getUserId();
            //有且仅有一条  自动登录
            return AccessTokenSaveRspDTO.builder().isAutoLogin(true).userId(userId).build();
        }
        return AccessTokenSaveRspDTO.builder().isAutoLogin(false).build();

    }

    @Override
    @Transactional
    public void bind(Long userId, String openId, Integer thirdPlatformType) {

        Assert.notNull(userId, "userId不能为空");
        if (StrUtil.isEmpty(openId)){
            throw new IllegalArgumentException("openId不能为空");
        }
        List<CompanyUserPlatformDO> userPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                .thirdPlatformType(ThirdPlatformTypeEnum.WECHAT.getValue())
                .platformId(openId).build());
        if (CollUtil.isEmpty(userPlatformDOS)){
            CompanyUserPlatformDO companyUserPlatformDO = new CompanyUserPlatformDO();
            companyUserPlatformDO.setPlatformId(openId);
            companyUserPlatformDO.setThirdPlatformType(thirdPlatformType);
            companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.YES.getValue());
            //companyUserPlatformDO.setThirdPlatformFollowStatus(ThirdPlatformFollowStatusEnum.NOT_FOLLOWED.getValue());
            companyUserPlatformDO.setCreateTime(new Date());
            companyUserPlatformDO.setUserId(userId);
            companyUserPlatformMapper.insertSelective(companyUserPlatformDO);
            return;
        }
        // 先解绑
        userPlatformDOS.stream().filter(e -> !e.getUserId().equals(userId))
        .forEach(userPlatformDO -> {
            userPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
            userPlatformDO.setUpdateTime(new Date());
            companyUserPlatformMapper.updateByPrimaryKeySelective(userPlatformDO);
        });

        Optional<CompanyUserPlatformDO> optional1 = userPlatformDOS.stream()
                .filter(e -> e.getUserId().equals(userId))
                .map(companyUserPlatformDO -> {
                    companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.YES.getValue());
                    companyUserPlatformDO.setUpdateTime(new Date());
                    companyUserPlatformMapper.updateByPrimaryKeySelective(companyUserPlatformDO);
                    return companyUserPlatformDO;
                }).findFirst();
        if (optional1.isPresent()){
            return;
        }

        Optional<CompanyUserPlatformDO> optional2 = userPlatformDOS.stream().filter(
                e -> !e.getUserId().equals(userId) && e.getUserId().equals(0l))
                .map(userPlatformDO -> {
                    userPlatformDO.setUserId(userId);
                    userPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.YES.getValue());
                    userPlatformDO.setUpdateTime(new Date());
                    companyUserPlatformMapper.updateByPrimaryKeySelective(userPlatformDO);
                    return userPlatformDO;
                }).findFirst();
        if (optional2.isPresent()){
            return;
        }

        CompanyUserPlatformDO userPlatformDO = userPlatformDOS.get(0);
        CompanyUserPlatformDO companyUserPlatformDO = new CompanyUserPlatformDO();
        companyUserPlatformDO.setPlatformId(openId);
        companyUserPlatformDO.setThirdPlatformType(thirdPlatformType);
        companyUserPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.YES.getValue());
        companyUserPlatformDO.setThirdPlatformFollowStatus(userPlatformDO.getThirdPlatformFollowStatus());
        companyUserPlatformDO.setPlatformToken(userPlatformDO.getPlatformToken());
        companyUserPlatformDO.setRefreshToken(userPlatformDO.getRefreshToken());
        companyUserPlatformDO.setNickname(userPlatformDO.getNickname());
        companyUserPlatformDO.setAvatar(userPlatformDO.getAvatar());
        companyUserPlatformDO.setUniqueId(userPlatformDO.getUniqueId());
        companyUserPlatformDO.setCreateTime(new Date());
        companyUserPlatformDO.setUserId(userId);
        companyUserPlatformMapper.insertSelective(companyUserPlatformDO);
    }

    @Override
    @Transactional
    public void unBind(Long userId, String openId, Integer thirdPlatformType) {
        Assert.notNull(userId, "userId不能为空");
        if (StrUtil.isEmpty(openId)){
            throw new IllegalArgumentException("openId不能为空");
        }
        List<CompanyUserPlatformDO> userPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                .userId(userId)
                .thirdPlatformType(thirdPlatformType)
                .platformId(openId).build());
        if (CollUtil.isEmpty(userPlatformDOS)){
            return;
        }
        userPlatformDOS.stream().forEach(userPlatformDO -> {

            userPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
            userPlatformDO.setUpdateTime(new Date());
            companyUserPlatformMapper.updateByPrimaryKeySelective(userPlatformDO);
        });
    }

    @Override
    @Transactional
    public void unBindForPc(Long userId, Integer thirdPlatformType) {
        Assert.notNull(userId, "userId不能为空");

        List<CompanyUserPlatformDO> userPlatformDOS = companyUserPlatformMapper
                .listBy(CompanyUserPlatformQO.builder()
                        .userId(userId)
                        .thirdPlatformType(thirdPlatformType).build());
        if (CollUtil.isEmpty(userPlatformDOS)){
            return;
        }
        userPlatformDOS.stream().forEach(userPlatformDO -> {

            userPlatformDO.setIsBind(CompanyUserPlatformIsBindEnum.NO.getValue());
            userPlatformDO.setUpdateTime(new Date());
            companyUserPlatformMapper.updateByPrimaryKeySelective(userPlatformDO);
        });
    }


}
